using System;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Host;
using System.Management.Automation;
using System.Collections.ObjectModel;

namespace PSSymbolStore.Manager
{
    public class SymStoreTask : ISymStoreTask, IDisposable
    {
        private readonly Runspace _runspace;

        public PSHost Host { get; set; }
        public string SymbolStoreLocation { get; set; }

        public SymStoreTask(PSHost host)
        {
            Host = host;

            var initialSessionState = InitialSessionState.CreateDefault();
            initialSessionState.ImportPSModule(new[] {@".\PSSymbolStore.dll"});
            _runspace = RunspaceFactory.CreateRunspace(Host, initialSessionState);
            _runspace.Open();
        }

        #region ISymStoreTask Members

        public SortableBindingList<AddTransaction> GetTransactions()
        {
            if (String.IsNullOrEmpty(SymbolStoreLocation))
            {
                throw new InvalidOperationException("No symbol store is available");
            }

            var transactions = new SortableBindingList<AddTransaction>();

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = _runspace;
                ps.AddCommand("Get-Transaction")
                    .AddParameter("SymbolStore", SymbolStoreLocation)
                    .AddParameter("All");

                Collection<AddTransaction> results = ps.Invoke<AddTransaction>();
                foreach (var transaction in results)
                {
                    transactions.Add(transaction);
                }
            }

            return transactions;
        }

        public void Delete(AddTransactionList transactions)
        {
            if (String.IsNullOrEmpty(SymbolStoreLocation))
            {
                throw new InvalidOperationException("No symbol store is available");
            }

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = _runspace;
                ps.AddCommand("Remove-Transaction")
                    .AddParameter("SymbolStore", SymbolStoreLocation)
                    .AddParameter("TransactionId", transactions.GetTransactionIds())
                    .AddParameter("Confirm")
                    .AddParameter("Verbose");

                ps.Invoke();
            }
        }

        public void Lock(AddTransactionList transactions)
        {
            if (String.IsNullOrEmpty(SymbolStoreLocation))
            {
                throw new InvalidOperationException("No symbol store is available");
            }

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = _runspace;
                ps.AddCommand("Lock-Transaction")
                    .AddParameter("SymbolStore", SymbolStoreLocation)
                    .AddParameter("TransactionId", transactions.GetTransactionIds())
                    .AddParameter("Verbose");

                ps.Invoke();
            }
        }

        public void Unlock(AddTransactionList transactions)
        {
            if (String.IsNullOrEmpty(SymbolStoreLocation))
            {
                throw new InvalidOperationException("No symbol store is available");
            }

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = _runspace;
                ps.AddCommand("Unlock-Transaction")
                    .AddParameter("SymbolStore", SymbolStoreLocation)
                    .AddParameter("TransactionId", transactions.GetTransactionIds())
                    .AddParameter("Verbose");

                ps.Invoke();
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            try
            {
                if ((_runspace != null)
                    && (_runspace.RunspaceStateInfo.State == RunspaceState.Opened))
                {
                    _runspace.Close();
                }
            }
            catch (InvalidRunspaceStateException)
            {
            }
        }

        #endregion
    }
}
